﻿/* 版本记录
 * 
 * */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using System.IO.Ports;
using System.Threading;
using GKQC.Common;
using GKQC.DbHelper.DbModels;
using System.Xml;
using GKQC.DbHelper.ViewModels;
using System.Windows.Forms.VisualStyles;
using System.Linq;

namespace GKQC.Machine
{
    /// <summary>
    /// 機型11022, 用來檢測CAP、DF、ESR、高頻阻抗
    /// </summary>
    public partial class FormLCR11022_FQC : QcFormBase,IMachine
    {
        #region 私有变量
        private bool isMonitor = false; //是否监听
        private int readTimeout = 1000; //com口读数据超时时间
        private int writeTimeout = 1000;//com口写数据超时时间
        private bool isClosing = false;
        private bool isListening = false;
        bool isGettingData = false;
        int currentRowIndex = 0;
        UserModel user;

        Form parentForm;
        //public List<Form> SubFormList { get; set; }
        public bool IsClosing { get; set; }

        //Settings.LcrType _LcrType = Settings.LcrType.LCR11022;
        //Settings.LcType _LcType = Settings.LcType.CH2311;
        ILcrMeter lcrMeter = null;
        List<ElectricViewModel> _ElectricViewModels;
        StandardView _StandardView;
        ReportSetModel _Report;
        double _Voltage;
        #endregion

        #region 构造函数
        public FormLCR11022_FQC(Form parentForm, UserModel user,double voltage, List<ElectricViewModel> electricViewModels, StandardView standardView
            , ReportSetModel report)
        {
            try
            {
                InitializeComponent();
                this.SubFormList = new List<Form>();
                this._Report = report;
                this._Voltage = voltage;
                //grid 显示行号
                this.Grid.Dock = DockStyle.Fill;
                this.Grid.AutoGenerateColumns = false;
                this.Grid.CellFormatting +=
                     new System.Windows.Forms.DataGridViewCellFormattingEventHandler(DataGridViewSet.CellFormatting);
                this.Grid.CellFormatting +=
                     new DataGridViewCellFormattingEventHandler(DataGridViewSet.CellFormattingForColor);

                this.parentForm = parentForm;
                this._ElectricViewModels = electricViewModels;
                this._StandardView = standardView;
                lblCapStand.Text = this._StandardView.CapMin.ToString() + "-" + this._StandardView.CapMax.ToString();
                if(this._StandardView.DfMax >0) lblDfStand.Text = "<" + this._StandardView.DfMax.ToString();
                if(this._StandardView.ZMax>0 ) lblZStand.Text = "<" + this._StandardView.ZMax.ToString();
                if(this._StandardView.EsrMax > 0)lblEsrStand.Text = "<" + this._StandardView.EsrMax.ToString();

                getPortBuad();
                InitCombo();

                this.user = user;
                BindingGrid();

                Settings.LcrType lcrType = Settings.GetLcrType();
                bool isAutoTest = Settings.IsAllAuto();
                if(lcrType !=  Settings.LcrType.SX10091A && !isAutoTest)
                {
                    cboZRFreq.Visible = false;
                    lblZRFreq.Visible = false;
                    lblCDFreq.Text = "频率：";
                    lblCDFreq.Location = new Point(lblCDFreq.Location.X + 15, lblCDFreq.Location.Y);
                }
                //_LcType = Settings.GetLcType();
                lcrMeter = MachineFactory.GetLcrMeter();

#if DEBUG
                //lcrMeter = new LcrMeterDebug();
#endif
                btnMonitor_Click(null, null);
                //Thread.Sleep(200);
                btSet_Click(null, null);

                RefreshTestGrid(0);
                SetStaticTxtWidth();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                MessageBox.Show(ex.Message, "異常S0034", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region 事件
        //grid 绘制行号
        private void Grid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Common.DataGridViewSet.RowPostPaint(sender, e);
        }
        //关闭程序
        private void FormLCR022_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                IsClosing = true;
                Grid.EndEdit();
                var m = parentForm.GetType().GetMethod("RefreshTestGrid");
                if (m != null && m.GetParameters().Length == 1)
                    m.Invoke(parentForm, new object[] { 0 });
                else if ((m != null && m.GetParameters().Length == 2))
                    m.Invoke(parentForm, new object[] { null, false });

                timer1.Enabled = false;
                if (Settings.GetLcrType() != Settings.LcrType.LCR11022)
                {
                    COMClose();
                    Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }

        }
        //时间每隔0.5秒读取一次
        private uint saveTick = 0; //个多久保存一次
        private string strData = "";

        //保存值到網格
        public bool isTrueGetting = false;
        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                isTrueGetting = true;
                timer1_Tick(timer1, new EventArgs());
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                MessageBox.Show(ex.Message, "異常0023", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
                
        }

        string CD = "CD";
        string R = "R";
        string Z = "Z";
        string ZR = "ZR";
        string CD_ZR = "CD-ZR";
        void Save()
        {
            if (!isTrueGetting) return;
            try
            {
                if (currentRowIndex > Grid.Rows.Count - 2) return;

                if (this.Grid.CurrentCell == null)
                {
                    this.Grid.Rows[0].Cells[0].Selected = true;
                }

                int rowIndex = this.Grid.CurrentCell.RowIndex;
                int columnIndex = this.Grid.CurrentCell.ColumnIndex;
                if (currentRowIndex < columnIndex) currentRowIndex = columnIndex;
                this.Grid.ClearSelection();
                string testItem = FormCommon.GetDataTableComboBoxValue(cboTestItem);
                if (testItem == CD) // c/d
                {
                    ColCap.Selected = true;
                    //this.Grid.Columns[0].Selected = true;
                    if (columnIndex != ColCap.Index && columnIndex != ColDf.Index)
                    {
                        rowIndex = 0;
                        currentRowIndex = 0;
                    }
                    columnIndex = ColCap.Index;
                }
                else if (testItem == R) //esr
                {
                    if (columnIndex != ColEsr.Index && columnIndex != ColEsr2.Index)
                    {
                        rowIndex = 0;
                        currentRowIndex = 0;
                        ColEsr.Selected = true;
                        columnIndex = ColEsr.Index;
                    }
                }
                else if (testItem == Z)//z
                {
                    if (columnIndex != ColZ.Index && columnIndex != ColZ2.Index)
                    {
                        rowIndex = 0;
                        currentRowIndex = 0;
                        columnIndex = ColZ.Index;
                        ColZ.Selected = true;
                    }
                }
                else if (testItem == ZR)//z/esr
                {
                    if (columnIndex != ColZ.Index && columnIndex != ColEsr.Index
                        && columnIndex != ColZ2.Index && columnIndex != ColEsr2.Index)
                    {
                        rowIndex = 0;
                        currentRowIndex = 0;
                        ColEsr.Selected = true;
                        columnIndex = ColZ.Index;
                    }
                }

                this.Grid.Rows[rowIndex].Cells[columnIndex].Selected = true;

                ElectricViewModel view = this.Grid.CurrentRow.DataBoundItem as ElectricViewModel;
                if (view != null)
                {
                    double value1 = 0;
                    double value2 = 0;

                    double cap = 0;
                    double df = 0;
                    double z = 0;
                    double r = 0;

                    if (testItem == CD) // c/d
                    {
                        if (double.TryParse(txtCAP.Text, out cap))
                        {
                            if (cap > 0)
                            {
                                view.CAP = cap;
                                view.CAPisValid = _StandardView.IsValid(ItemCode.CAP, cap);
                            }
                            else
                                return;
                        }
                        if (double.TryParse(txtDF.Text, out df))
                        {
                            if (df > 0)
                            {
                                view.DF = df;
                                view.DFisValid = _StandardView.IsValid(ItemCode.DF, df);
                            }
                            else return;
                        }
                    }
                    else if (testItem == R)//esr
                    {
                        if (double.TryParse(txtESR.Text, out r))
                        {
                            if (r > 0)
                            {
                                if (columnIndex != ColZ2.Index && columnIndex != ColEsr2.Index)
                                {
                                    view.ESR = r;
                                    view.ESRisValid = _StandardView.IsValid(ItemCode.ESR, r);
                                }
                                else
                                {
                                    view.ESR2 = r;
                                    view.ESR2isValid = _StandardView.IsValid(ItemCode.ESR2, r);
                                }
                            }
                        }
                    }
                    else if (testItem == Z)//z
                    {
                        if (double.TryParse(txtZ.Text, out z))
                        {
                            if (z > 0)
                            {
                                if (columnIndex != ColZ2.Index && columnIndex != ColEsr2.Index)
                                {

                                    view.Z = z;
                                    view.ZisValid = _StandardView.IsValid(ItemCode.Z, z);
                                }
                                else
                                {
                                    view.Z2 = z;
                                    view.Z2isValid = _StandardView.IsValid(ItemCode.Z2, z);
                                }
                            }
                        }
                    }
                    else if (testItem == ZR)// z/esr
                    {
                        if (double.TryParse(txtZ.Text, out z))
                        {
                            if (z > 0)
                            {
                                if (columnIndex != ColZ2.Index && columnIndex != ColEsr2.Index)
                                {

                                    view.Z = z;
                                    view.ZisValid = _StandardView.IsValid(ItemCode.Z, z);
                                }
                                else
                                {
                                    view.Z2 = z;
                                    view.Z2isValid = _StandardView.IsValid(ItemCode.Z2, z);
                                }
                            }
                        }
                        if (double.TryParse(txtESR.Text, out r))
                        {
                            if (r > 0)
                            {
                                if (columnIndex != ColZ2.Index && columnIndex != ColEsr2.Index)
                                {
                                    view.ESR = r;
                                    view.ESRisValid = _StandardView.IsValid(ItemCode.ESR, r);
                                }
                                else
                                {
                                    view.ESR2 = r;
                                    view.ESR2isValid = _StandardView.IsValid(ItemCode.ESR2, r);
                                }
                            }
                        }
                    }
                    else if (testItem == CD_ZR)
                    {
                        if (double.TryParse(txtCAP.Text, out cap))
                        {
                            if (cap > 0)
                            {
                                view.CAP = cap;
                                view.CAPisValid = _StandardView.IsValid(ItemCode.CAP, cap);
                            }
                        }
                        if (double.TryParse(txtDF.Text, out df))
                        {
                            if (df > 0)
                            {
                                view.DF = df;
                                view.DFisValid = _StandardView.IsValid(ItemCode.DF, df);
                            }
                        }

                        if (double.TryParse(txtZ.Text, out z))
                        {
                            if (z > 0)
                            {
                                if (columnIndex != ColZ2.Index && columnIndex != ColEsr2.Index)
                                {

                                    view.Z = z;
                                    view.ZisValid = _StandardView.IsValid(ItemCode.Z, z);
                                }
                                else
                                {
                                    view.Z2 = z;
                                    view.Z2isValid = _StandardView.IsValid(ItemCode.Z2, z);
                                }
                            }
                        }
                        if (double.TryParse(txtESR.Text, out r))
                        {
                            if (r > 0)
                            {
                                if (columnIndex != ColZ2.Index && columnIndex != ColEsr2.Index)
                                {
                                    view.ESR = r;
                                    view.ESRisValid = _StandardView.IsValid(ItemCode.ESR, r);
                                }
                                else
                                {
                                    view.ESR2 = r;
                                    view.ESR2isValid = _StandardView.IsValid(ItemCode.ESR2, r);
                                }
                            }
                        }
                    }

                    currentRowIndex++;
                }
                try
                {
                    if (rowIndex + 1 < this.Grid.Rows.Count)
                        this.Grid.Rows[rowIndex + 1].Cells[this.Grid.CurrentCell.ColumnIndex].Selected = true;
                }
                catch { }

                lcrMeter.Local(sp);

                this.Grid.Refresh();
                RefreshTestGrid(0);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                MessageBox.Show(ex.Message, "異常0023", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                isTrueGetting = false;
            }
        }

        //监听LCR
        private void btnMonitor_Click(object sender, EventArgs e)
        {
            try
            {
                isSetting = true;
                if (isMonitor == true) //监听否
                {
                    isMonitor = false;
                    btnMonitor.ForeColor = Color.Black;
                    btnMonitor.Text = "打开LCR仪器(&L)";
                    this.timer1.Enabled = false;
                    Thread.Sleep(300);
                    COMClose();

                    txtCAP.Text = "";
                    txtDF.Text = "";
                    txtESR.Text = "";
                    txtZ.Text = "";
                }
                else
                {
                    isMonitor = true;
                    btnMonitor.ForeColor = Color.Red;
                    btnMonitor.Text = "请测试！(&L)";
                    if (!sp.IsOpen)
                    {
                        isClosing = false;
                        isListening = false;
                        StartSerialPort();

                        Thread.Sleep(300);
                        lcrMeter.Remote(sp);
                    }


                    btnSave.Focus();
                    
                    this.timer1.Interval = 500;//todo: timer.Interval 是否参数化;
                    //this.timer1.Enabled = true;


                    //toolStripStatusLabel1.Text = "定时器:" + this.timerInterval.ToString() + "ms [串口] 端口:" + sp.PortName + "  波特率:" + sp.BaudRate.ToString() + "  校验位" + sp.Parity.ToString() + "  数据位:" + sp.DataBits.ToString() + "  停止位:" + sp.StopBits.ToString();
                    //toolStripStatusLabel1.Text = "串口:" + sp.PortName + "  波特率:" + sp.BaudRate.ToString();
                }
            }
            catch (Exception ex)
            {

                Logger.LogError(ex);
                //MessageBox.Show("未能成功开启对LCR的监听");
            }
            finally
            {
                isSetting = false;
#if DEBUG
                //this.timer1.Enabled = true;
#endif
            }
        }


        //检测项目选择关闭后定位到保存按钮
        private void cbTestItem_SelectionChangeCommitted(object sender, EventArgs e)
        {
            this.btnSave.Focus();
        }


        //设置
        private void btSet_Click(object sender, EventArgs e)
        {
            try
            {
                isSetting = true;
                if (this.sp.IsOpen)
                {
                    string freq = FormCommon.GetDataTableComboBoxValue(cboCDFreq);//GetFreqItem();
                    string freq2 = FormCommon.GetDataTableComboBoxValue(cboZRFreq);
                    string testItem = FormCommon.GetDataTableComboBoxValue(cboTestItem);
                    lcrMeter.Remote(sp);
                    isSetting = true;
                    Thread.Sleep(200);
                    lcrMeter.SetFreq(sp, freq, freq2, testItem);
                    isSetting = true;
                    Thread.Sleep(200);
                    lcrMeter.Local(sp);
                    Thread.Sleep(200);
                    isSetting = true;
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                MessageBox.Show(ex.Message, "異常S0033", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                isSetting = false;
            }
        }

        #endregion

        #region 方法
        //初始化combo
        private void InitCombo()
        {
            #region 测试项目
            DataTable dt = MachineFactory.GetTestItemTable();
            Settings.LcrType lcrType = Settings.GetLcrType();
            if (lcrType != Settings.LcrType.SX10091A)
            {
                foreach (DataRow r in dt.Rows)
                {
                    if (r["Value"].ToString() == "CD-ZR")
                    {
                        dt.Rows.Remove(r);
                        break;
                    }
                }
            }
            this.cboTestItem.ValueMember = "Value";
            this.cboTestItem.DisplayMember = "Name";
            this.cboTestItem.DataSource = dt;
            this.cboTestItem.DropDownStyle = ComboBoxStyle.DropDownList;//设置combobox2的样式
            this.cboTestItem.SelectedIndex = 0;
            #endregion

            #region lcr 频率
            DataTable dtFreq = MachineFactory.GetLcrFrequencyTable();
            this.cboCDFreq.ValueMember = "Value";
            this.cboCDFreq.DisplayMember = "Name";
            this.cboCDFreq.DataSource = dtFreq;
            this.cboCDFreq.DropDownStyle = ComboBoxStyle.DropDownList;//设置combobox2的样式
            this.cboCDFreq.SelectedIndex = 0;

            DataTable dtZRFreq = dtFreq.Copy();
            this.cboZRFreq.ValueMember = "Value";
            this.cboZRFreq.DisplayMember = "Name";
            this.cboZRFreq.DataSource = dtZRFreq;
            this.cboZRFreq.DropDownStyle = ComboBoxStyle.DropDownList;//设置combobox2的样式
            this.cboZRFreq.SelectedIndex = 1;
            #endregion
        }

        //初始化gird
        private void BindingGrid()
        {
            this.Grid.DataSource = new BindingList<ElectricViewModel>(this._ElectricViewModels);
            SetStaticTxtWidth();
        }

        //开始监听
        private void StartSerialPort()
        {
            if (!sp.IsOpen)
            {
                this.sp.ReadTimeout = this.readTimeout;
                this.sp.WriteTimeout = this.writeTimeout; //写数据超时时间
                this.sp.Handshake = Handshake.None; //流量控制
                try
                {
                    this.sp.Open();  //开启串口
                    this.sp.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.sp_DataReceived);
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex);
                }
            }
        }

        //獲取端口和波特率
        private void getPortBuad()
        {
            Settings.GetPortBuad(sp, Settings.MachineType.LCR);
        }

        #endregion

        //串口发生错误
        private void sp_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            try
            {
                isMonitor = false;
                btnMonitor.ForeColor = Color.Black;
                btnMonitor.Text = "监听LCR仪器(&L)";
                this.timer1.Enabled = false;
                sp.Close();
                txtCAP.Text = "";
                txtDF.Text = "";
                txtESR.Text = "";
                txtZ.Text = "";
                //Logger.LogMessage("串口发生错误,错误代码：" + e.EventType.ToString());
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }


        BackgroundWorker dataReceiedWorker;
        //接收到串口数据事件
        private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            try
            {
                if (isClosing) //如果窗口关闭就结束串口处理过程
                    return;
                Thread.Sleep(45); //暂停下，否则获取数据不完整
                isListening = true;

                string data1 = string.Empty;
                if (dataReceiedWorker == null)
                {
                    dataReceiedWorker = new BackgroundWorker();
                    dataReceiedWorker.DoWork += (s, a) =>
                    {
                        data1 = lcrMeter.GetData(sp);
                    };
                    dataReceiedWorker.RunWorkerCompleted += (s, a) =>
                    {
                        UpdateRecevie(data1);
                    };
                }
                dataReceiedWorker.RunWorkerAsync();

                /*
                string data = lcrMeter.GetData(sp); //获取串口返回的数据                               

                //匿名委托，用于this.Invoke调用
                //说明：由于.net 2.0以后的控件不能跨线程访问,需要使用委托来更新控件数据
                EventHandler DelUpdate = delegate
                {
                    UpdateRecevie(data); //显示数据                   
                };

                //this.Invoke(DelUpdate);
                if(this.IsHandleCreated)
                    this.BeginInvoke(DelUpdate);
                */
                
            }
            catch (System.Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        /// <summary>
        /// 显示数据
        /// </summary>
        /// <param name="NewData"></param>
        public void UpdateRecevie(object NewData)
        {
            try
            {
                //解析数据
                decimal cap, df, z, r;
                string seletItem = FormCommon.GetDataTableComboBoxValue(cboTestItem);
                bool bRet = lcrMeter.AnalysisData(NewData as string, out cap, out df, out z, out r, seletItem, string.Empty, false);
                //Logger.LogMessage("UpdateRecevie:" + NewData.ToString()); //调试用
                //Logger.LogMessage("A");
                if (cap > 1000000 || z > 1000000 || r > 1000000) return; 
                //Logger.LogMessage("B");
                if (bRet)
                {
                    if(seletItem == CD)
                    {
                        txtCAP.Text = cap.ToString();// Math.Round(data1 * 1000000m, 3).ToString();
                        txtDF.Text = df.ToString();//(Math.Round(data2*100m, 2)).ToString();
                    }
                    else if(seletItem == R)
                    {
                        txtESR.Text = r.ToString();
                    }
                    else if (seletItem == Z)
                    {
                        txtZ.Text = z.ToString();
                    }
                    else if (seletItem == ZR)
                    {
                        txtZ.Text = z.ToString();// (Math.Round(data1 * 1000m, 2)).ToString(); //data1.ToString();
                        txtESR.Text = r.ToString();// (Math.Round(data2 * 1000m, 2)).ToString();
                    }
                    else if (seletItem == CD_ZR)
                    {
                        txtCAP.Text = cap.ToString();
                        txtDF.Text = df.ToString();
                        txtESR.Text = r.ToString();
                        txtZ.Text = z.ToString();
                    }
                    else
                    {
                        txtCAP.Text = zeroString;
                        txtDF.Text = zeroString;
                        txtESR.Text = zeroString;
                        txtZ.Text = zeroString;
                    }

                    if (isTrueGetting)
                    {
                        Save();
                    }
                }

                isListening = false;
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        string zeroString = "0";
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (isGettingData) return;
            try
            {
                isGettingData = true;
                string testItem = FormCommon.GetDataTableComboBoxValue(cboTestItem);
                switch (testItem)
                {
                    case "CD-ZR"://"CAP和DF";
                        break;
                    case "CD"://"CAP和DF";
                        txtESR.Text = "";//
                        txtZ.Text = "";
                        break;
                    case "R"://"ESR";
                        txtCAP.Text = "";
                        txtDF.Text = "";
                        txtZ.Text = "";
                        break;
                    case "Z"://"Z";
                        txtCAP.Text = "";
                        txtDF.Text = "";
                        txtESR.Text = "";
                        break;
                    case "ZR"://"Z/ESR";
                        txtCAP.Text = "";
                        txtDF.Text = "";
                        //txtESR.Text = "";
                        break;
                }
                isSetting = true;
                lcrMeter.Remote(sp);
                isSetting = false;
                Thread.Sleep(200);
                lcrMeter.Fetch(sp, testItem);
                Thread.Sleep(50);
            }
            catch (TimeoutException toEx)
            {
                Logger.LogError(toEx);
                Logger.LogMessage(strData);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                Logger.LogMessage(strData);
            }
            finally
            {
                isGettingData = false;
#if DEBUG
                //txtESR.Text = (RandomSugar.GetFormatedNumeric(2200, 4200) / 100m).ToString();
                //txtZ.Text = (RandomSugar.GetFormatedNumeric(160, 220) / 100m).ToString(); ;
                //txtCAP.Text = (RandomSugar.GetFormatedNumeric(1600, 2200) / 100m).ToString();
                //txtDF.Text = (RandomSugar.GetFormatedNumeric(400, 800) / 100m).ToString();
#endif
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <returns></returns>
        private bool COMClose()
        {
            try
            {
                if (timer1.Enabled) timer1.Enabled = false;
                this.sp.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(this.sp_DataReceived);
                if (sp.IsOpen)
                {
                    isClosing = true;
                    while (isListening) //如果com口还未退出则等待com口线程结束
                        Application.DoEvents();

                    Thread.Sleep(200);
                    sp.Close();
                    Thread.Sleep(200);
                }
                return true;
            }
            catch (System.Exception ex)
            {
                Logger.LogError(ex);
                return false;
            }
        }
        
        bool isSetting = false;
        //检测项目改变后
        private void cbTestItem_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                isSetting = true;
                if (isMonitor)
                {

                    string testItem = FormCommon.GetDataTableComboBoxValue(cboTestItem);

                    lcrMeter.Remote(sp);
                    isSetting = true;
                    Thread.Sleep(200);
                    lcrMeter.Fetch(sp, testItem);
                    isSetting = true;
                    Thread.Sleep(200);

                    if (!cboZRFreq.Visible)
                    {
                        if (testItem == "ZR" || testItem == "Z" || testItem == "R")
                            cboCDFreq.SelectedIndex = 1;
                        else if (testItem == "CD")
                            cboCDFreq.SelectedIndex = 0;
                    }
                    else
                    {

                    }
                    //isSetting = true;
                    //btSet_Click(null, null); //设置检测频率
                    //isSetting = true;

                    if (testItem == "CD" &&
                        (Grid.CurrentCell == null || Grid.CurrentCell.ColumnIndex > 1))
                        currentRowIndex = 0;
                    else if (testItem == "ZR" && (Grid.CurrentCell == null || Grid.CurrentCell.ColumnIndex < 3))
                        currentRowIndex = 0;
                    else if (testItem == "Z" && (Grid.CurrentCell == null || Grid.CurrentCell.ColumnIndex != 3))
                        currentRowIndex = 0;
                    else if (testItem == "R" && (Grid.CurrentCell == null || Grid.CurrentCell.ColumnIndex != 4))
                        currentRowIndex = 0;
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
            finally
            {
                isSetting = false;
            }
        }


        private void cboFreq_SelectedIndexChanged(object sender, EventArgs e)
        {
            btSet_Click(null, null); //设置检测频率
            btnSave.Focus();
        }

        public void RefreshGrid()
        {
            Grid.Refresh();
        }

        public void RefreshTestGrid(int i)
        {
            Grid.Refresh();

            var varCap = _ElectricViewModels.Where(r => r.CAP > 0);
            var varDF = _ElectricViewModels.Where(r => r.DF > 0);
            var varLC = _ElectricViewModels.Where(r => r.LC > 0);
            var varZ = _ElectricViewModels.Where(r => r.Z > 0);
            var varESR = _ElectricViewModels.Where(r => r.ESR > 0);            
            
            if (varCap.Any())
            {
                txtCapAvg.Text = Math.Round(varCap.Average(r => r.CAP), 2).ToString();
                double maxCap = varCap.Max(r => r.CAP);
                txtCapMax.Text = maxCap.ToString();
                double minCap = varCap.Min(r => r.CAP);
                txtCapMin.Text = minCap.ToString(); 
                txtCapR.Text = Math.Round(maxCap - minCap, 2).ToString();
            }

            if (varDF.Any())
            {
                txtDfAvg.Text = Math.Round(varDF.Average(r => r.DF), 2).ToString();
                double maxDF = varDF.Max(r => r.DF);
                txtDfMax.Text = maxDF.ToString();
                double minDF = varDF.Min(r => r.DF);
                txtDfMin.Text = minDF.ToString();
                txtDfR.Text = Math.Round(maxDF - minDF, 2).ToString();
            }

            if (varLC.Any())
            {
                txtLcAvg.Text = Math.Round(varLC.Average(r => r.LC), 2).ToString();
                double maxLC = varLC.Max(r => r.LC);
                txtLcMax.Text = maxLC.ToString();
                double minLC = varLC.Min(r => r.LC);
                txtLcMin.Text = minLC.ToString();
                txtLcR.Text = Math.Round(maxLC - minLC, 2).ToString();
            }

            if (varZ.Any())
            {
                txtZAvg.Text = Math.Round(varZ.Average(r => r.Z), 2).ToString();
                double maxZ = varZ.Max(r => r.Z);
                txtZMax.Text = maxZ.ToString();
                double minZ = varZ.Min(r => r.Z);
                txtZMin.Text = minZ.ToString();
                txtZR.Text = Math.Round(maxZ - minZ, 2).ToString();
            }

            if (varESR.Any())
            {
                txtEsrAvg.Text = Math.Round(varESR.Average(r => r.ESR), 2).ToString();
                double maxESR = varESR.Max(r => r.ESR);
                txtEsrMax.Text = maxESR.ToString();
                double minESR = varESR.Min(r => r.ESR);
                txtEsrMin.Text = minESR.ToString();
                txtEsrR.Text = Math.Round(maxESR - minESR, 2).ToString();
            }

        }
    
        void SetStaticTxtWidth()
        {
            lblAvg.Width = Grid.RowHeadersWidth;
            lblMax.Width = Grid.RowHeadersWidth;
            lblMin.Width = Grid.RowHeadersWidth;
            lblR.Width = Grid.RowHeadersWidth;

            txtCapAvg.Width = ColCap.Width;
            txtCapAvg.Location = new Point(lblAvg.Location.X + lblAvg.Width, lblAvg.Location.Y);
            txtCapMax.Width = ColCap.Width;
            txtCapMax.Location = new Point(lblMax.Location.X + lblMax.Width, lblMax.Location.Y);
            txtCapMin.Width = ColCap.Width;
            txtCapMin.Location = new Point(lblMin.Location.X + lblMin.Width, lblMin.Location.Y);
            txtCapR.Width = ColCap.Width;
            txtCapR.Location = new Point(lblR.Location.X + lblR.Width, lblR.Location.Y);

            txtDfAvg.Width = ColDf.Width;
            txtDfAvg.Location = new Point(txtCapAvg.Location.X + txtCapAvg.Width, lblAvg.Location.Y);
            txtDfMax.Width = ColDf.Width;
            txtDfMax.Location = new Point(txtCapAvg.Location.X + txtCapAvg.Width, lblMax.Location.Y);
            txtDfMin.Width = ColDf.Width;
            txtDfMin.Location = new Point(txtCapAvg.Location.X + txtCapAvg.Width, lblMin.Location.Y);
            txtDfR.Width = ColDf.Width;
            txtDfR.Location = new Point(txtCapAvg.Location.X + txtCapAvg.Width, lblR.Location.Y);

            txtLcAvg.Width = ColLc.Width;
            txtLcAvg.Location = new Point(txtDfAvg.Location.X + txtDfAvg.Width, lblAvg.Location.Y);
            txtLcMax.Width = ColLc.Width;
            txtLcMax.Location = new Point(txtDfAvg.Location.X + txtDfAvg.Width, lblMax.Location.Y);
            txtLcMin.Width = ColLc.Width;
            txtLcMin.Location = new Point(txtDfAvg.Location.X + txtDfAvg.Width, lblMin.Location.Y);
            txtLcR.Width =   ColLc.Width;
            txtLcR.Location = new Point(txtDfAvg.Location.X + txtDfAvg.Width, lblR.Location.Y);

            txtZAvg.Width = ColZ.Width;
            txtZAvg.Location = new Point(txtLcAvg.Location.X + txtLcAvg.Width, lblAvg.Location.Y);
            txtZMax.Width = ColZ.Width;
            txtZMax.Location = new Point(txtLcAvg.Location.X + txtLcAvg.Width, lblMax.Location.Y);
            txtZMin.Width = ColZ.Width;
            txtZMin.Location = new Point(txtLcAvg.Location.X + txtLcAvg.Width, lblMin.Location.Y);
            txtZR.Width =   ColZ.Width;
            txtZR.Location = new Point(txtLcAvg.Location.X + txtLcAvg.Width, lblR.Location.Y);

            txtEsrAvg.Width = ColEsr.Width;
            txtEsrAvg.Location = new Point(txtZAvg.Location.X + txtZAvg.Width, lblAvg.Location.Y);
            txtEsrMax.Width = ColEsr.Width;
            txtEsrMax.Location = new Point(txtZAvg.Location.X + txtZAvg.Width, lblMax.Location.Y);
            txtEsrMin.Width = ColEsr.Width;
            txtEsrMin.Location = new Point(txtZAvg.Location.X + txtZAvg.Width, lblMin.Location.Y);
            txtEsrR.Width =   ColEsr.Width;
            txtEsrR.Location = new Point(txtZAvg.Location.X + txtZAvg.Width, lblR.Location.Y);
        }


        private void Grid_SelectionChanged(object sender, EventArgs e)
        {
            if (Grid.CurrentCell != null && Grid.CurrentCell.RowIndex < Grid.Rows.Count-1)
                currentRowIndex = Grid.CurrentCell.RowIndex;
            else if(Grid.CurrentCell == null)
                currentRowIndex = 0;
        }

        #region 右鍵菜單
        private void tsmClear_Click(object sender, EventArgs e)
        {
            if (Grid.CurrentCell != null) Grid.CurrentCell.Value = null;
        }

        private void tsmClearColumn_Click(object sender, EventArgs e)
        {
            try
            {
                if (MessageBox.Show("即將清除當前列數據，請確認", "請確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)
                    == DialogResult.Cancel)
                    return;

                if (Grid.CurrentCell != null)
                {
                    int colmnIndex = Grid.CurrentCell.ColumnIndex;
                    for (int i = 0; i < Grid.Rows.Count; i++)
                    {
                        Grid.Rows[i].Cells[colmnIndex].Value = null;
                    }
                }
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
                //MessageBox.Show(ex.Message, "異常S0035", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void tsmClearAll_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("即將清除網格所有數據，請確認", "請確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question,MessageBoxDefaultButton.Button2)
                == DialogResult.Cancel)
                return;

            foreach (ElectricViewModel v in this._ElectricViewModels)
            {
                v.Clear();
            }
            this.Grid.Refresh();
        }
        #endregion 右鍵菜單

        bool isESCcancel = false;
        private void Grid_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            
            try
            {
                if (Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType == typeof(Double)
                    || Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType == typeof(Decimal))
                {
                    Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = 0;
                    e.Cancel = true;
                    SendKeys.Send("{ESC}");
                    isESCcancel = true;
                }
            }
            catch (Exception ex)
            {

            }
        }

        private void Grid_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space)
                e.SuppressKeyPress = false;
        }

        public void SetZ2Visible(bool isVisible)
        {
            ColZ2.Visible = isVisible;
        }
        public void SetLc2Visible(bool isVisible)
        {
            ColLc2.Visible = isVisible;
        }

        public void SetEsr2Visible(bool isVisible)
        {
            ColEsr2.Visible = isVisible;
        }

        private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
        {

        }

        private void btnLc_Click(object sender, EventArgs e)
        {
            try
            {
                if (MachineFactory.ExistsTestForm(TestType.Lc, SubFormList)) return;
                var lcForm = MachineFactory.GetLcForm(this, user, _Voltage, _ElectricViewModels, _StandardView
                    , _Report);

                try
                {
                    if (lcForm == null) return;
                    var lcQcForm = lcForm as QcFormBase;
                    if (lcQcForm != null && this.Text != "LCR METER FQC/OQC")
                    {
                        lcQcForm.SetTitle(this.Text);
                    }
                }
                catch(Exception ex)
                {
                    Logger.LogError(ex);
                }
                Form f = lcForm as Form;
                SubFormList.Add(f);
                f.Show();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                MessageBox.Show(ex.Message, "異常S0042", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void FormLCR11022_FQC_Resize(object sender, EventArgs e)
        {
            SetStaticTxtWidth();
        }

        private void FormLCR11022_FQC_Shown(object sender, EventArgs e)
        {
            SetStaticTxtWidth();
        }

        private void Grid_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                ElectricViewModel view = this.Grid.CurrentRow.DataBoundItem as ElectricViewModel;
                if (view == null) return;

                double value = 0;
                if(Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == null)
                {
                    Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "0";
                    return;
                }
                double.TryParse(Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(), out value);

                if (this.Grid.Columns[e.ColumnIndex] == ColCap)
                {
                    view.CAPisValid = _StandardView.IsValid(ItemCode.CAP, value);
                }
                else if (this.Grid.Columns[e.ColumnIndex] == ColDf)
                {
                    view.DFisValid = _StandardView.IsValid(ItemCode.DF, value);
                }
                else if (this.Grid.Columns[e.ColumnIndex] == ColLc)
                {
                    view.LCisValid = _StandardView.IsValid(ItemCode.LC, value);
                }
                else if (this.Grid.Columns[e.ColumnIndex] == ColLc2)
                {
                    view.LC2isValid = _StandardView.IsValid(ItemCode.LC2, value);
                }
                else if (this.Grid.Columns[e.ColumnIndex] == ColEsr)
                {
                    view.ESRisValid = _StandardView.IsValid(ItemCode.ESR, value);
                }
                else if (this.Grid.Columns[e.ColumnIndex] == ColEsr2)
                {
                    view.ESR2isValid = _StandardView.IsValid(ItemCode.ESR2, value);
                }
                else if (this.Grid.Columns[e.ColumnIndex] == ColZ)
                {
                    view.ZisValid = _StandardView.IsValid(ItemCode.Z, value);
                }
                else if (this.Grid.Columns[e.ColumnIndex] == ColZ2)
                {
                    view.Z2isValid = _StandardView.IsValid(ItemCode.Z2, value);
                }

                this.Grid.Refresh();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        private void Grid_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if(Grid.CurrentCell.Value == null || Grid.CurrentCell.Value.ToString() ==string.Empty)
            {
                Grid.CurrentCell.Value = 0;
            }
        }

        private void Grid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (isESCcancel)
                {
                    isESCcancel = false;
                    if (e.RowIndex < Grid.Rows.Count - 1)
                    {

                        Grid.CurrentCell = Grid.Rows[e.RowIndex + 1].Cells[e.ColumnIndex];
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }
    }
}
